e52fbf0e79796e44daec3f6c50722edb4cdd696d,core/typesystemEngine/source/jetbrains/mps/lang/typesystem/runtime/DoubleRuleSet.java,DoubleRuleSet,get,#Pair#,59

Before Change


        }
      }
    }
    result = Collections.synchronizedSet(new HashSet<T>(1));
    myRules.putIfAbsent(key, result);
    myRulesCache.putIfAbsent(key, new HashSet<T>(1));
    return Collections.unmodifiableSet(result);

After Change


    return get(new Pair<String, String>(node1.getConceptFqName(), node2.getConceptFqName()));
  }

  protected Set<T> get(@NotNull final Pair<String, String> key) {
    Set<T> result = myRulesCache.get(key);
    if(result != null) {
      return result;
    }

    String c1 = key.o1;
    String c2 = key.o2;
    if (!isInterfaceConcept(c1) && !isInterfaceConcept(c2)) {
      for (String conceptDeclaration1 = c1; conceptDeclaration1 != null; conceptDeclaration1 = getSuperConcept(conceptDeclaration1)) {
        for (String conceptDeclaration2 = c2; conceptDeclaration2 != null; conceptDeclaration2 = getSuperConcept(conceptDeclaration2)) {
          Pair<String, String> newKey =
            new Pair<String, String>(conceptDeclaration1, conceptDeclaration2);
          result = myRules.get(newKey);
          if (result != null) {
            if (conceptDeclaration1 != key.o1 || conceptDeclaration2 != key.o2) {
              myRules.putIfAbsent(key, result);
            }
            // synchronized collection (result) requires external synchronization for iteration/clone
            synchronized (result) {
              Set<T> clone = Collections.unmodifiableSet(new THashSet<T>(result));
              myRulesCache.putIfAbsent(key, clone);
            }
            return Collections.unmodifiableSet(result);
          }
        }
      }
    }
    myRules.putIfAbsent(key, Collections.synchronizedSet(new HashSet<T>(1)));
    myRulesCache.putIfAbsent(key, Collections.<T>emptySet());
    return Collections.emptySet();
  }